package main

import (
	"github.com/grpc-ecosystem/go-grpc-middleware/auth"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/reflection"
	"google.golang.org/grpc/status"
	"log"
	pb "myrpc/stringlength/stringlength"
	"net"
)

const (
	port = ":50051"
)

type StringLengthServer struct {
}

func (s StringLengthServer) StringLength(ctx context.Context, source *pb.StringSource) (*pb.LengthResult, error) {
	length := int32(len(source.Source))
	return &pb.LengthResult{Length: length}, nil
}

func parseToken(token string) (struct{}, error) {
	// TODO parse token to user-info
	return struct{}{}, nil
}

func myAuthFunc(ctx context.Context) (context.Context, error) {
	token, err := grpc_auth.AuthFromMD(ctx, "bearer")
	if err != nil {
		log.Printf("can not get auth info from context. %v", token)
		return nil, err
	}
	userinfo, err := parseToken(token)
	if err != nil {
		return nil, status.Errorf(codes.Unauthenticated, "invalid auth token %s", token)
	}
	log.Printf("user-info %v", userinfo)
	return ctx, nil
}

func main() {
	lsr, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalf("failed to listen at port %s. %v", port, err)
	}
	log.Println("listen at ", port)
	server := grpc.NewServer(
		grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(myAuthFunc)),
	)
	pb.RegisterStringLengthServiceServer(server, &StringLengthServer{})
	reflection.Register(server)
	if err := server.Serve(lsr); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}

}
